<template>
    <div>
        <Cascader
            v-model="select"
            :data="data"
            :load-data="loadData"
            transfer
            :disabled="disabled"
            :size="size"
            :placeholder="placeholder"
            :render-format="renderFormat"
            @on-change="handleChange"
        />
    </div>
</template>

<script>
import areaData from 'area-data'
import util from './util'
const levelShow = (level, code) => {
  if (level === 2) {
    return Object.keys(areaData['86']).indexOf(code) > -1
  } else if (level === 3) {
    return true
  }
}
export default {
  name: 'alCascader',
  props: {
    value: Array,
    level: {
      type: [Number, String],
      default: 3,
      validator: val => {
        return util.checkLevel(parseInt(val))
      }
    },
    dataType: {
      type: String,
      default: 'all',
      validator: val => {
        return util.oneOf(val, util.dataType)
      }
    },
    disabled: {
      type: Boolean,
      default: false
    },
    size: String,
    placeholder: String,
    renderFormat: Function
  },
  data () {
    return {
      data: [],
      select: [],
      isInit: true,
      oldData: []
    }
  },
  computed: {
    showLevel () {
      return parseInt(this.level)
    }
  },
  methods: {
    init () {
      let proData = []
      for (const p in areaData['86']) {
        let proitem = {
          value: p,
          label: areaData['86'][p],
          children: []
        }
        if (this.showLevel > 0 && areaData[p]) {
          proitem.loading = false
        }
        proData.push(proitem)
      }
      this.data = proData
    },
    setDefaultValue () {
      if (this.value[0]) {
        let select = []
        if (isNaN(parseInt(this.value[0]))) {
          let i = 0
          let index = ''
          while (this.value[i] && i <= this.showLevel) {
            if (i === 0) {
              index = util.getIndex(areaData['86'], this.value[0])
            } else {
              index = util.getIndex(areaData[index], this.value[i])
            }
            select.push(index)
            i++
          }
          this.select = select
        } else {
          this.select = this.value
        }
        let res = this.procesValue(this.select)
        this.oldData = res
        this.$emit('input', res)
        this.$emit('on-change', res)
      }
    },
    canEmit (res) {
      let ifEmit = false
      if (this.value && this.value.length !== 0) {
        if (typeof res[0] === 'string') {
          if (this.value[this.value.length - 1] !== this.oldData[this.oldData.length - 1]) {
            ifEmit = true
          }
        } else {
          if (this.oldData && this.oldData.length !== 0 && this.value[this.value.length - 1].code !== this.oldData[this.oldData.length - 1].code) {
            ifEmit = true
          }
        }
      } else {
        ifEmit = true
      }
      return ifEmit
    },
    handleChange (resArr) {
      let res = this.procesValue(resArr)
      this.oldData = res
      this.$emit('input', res)
      this.$emit('on-change', res)
    },
    loadData (item, callback) {
      let childData = []
      let childs = areaData[item.value]
      for (const c in childs) {
        let childitem = {
          value: c,
          label: areaData[item.value][c],
          children: []
        }
        if (areaData[childitem.value] && levelShow(this.showLevel, item.value)) {
          childitem.loading = false
        }
        childData.push(childitem)
        item.children = childData
      }
      item.loading = false
      callback()
    },
    procesValue (arr) {
      let i = 0
      let res = []
      while (arr[i]) {
        let name = ''
        if (i === 0) {
          name = areaData['86'][arr[i]]
        } else {
          name = areaData[arr[i - 1]][arr[i]]
        }
        let item
        if (this.dataType === 'all') {
          item = {
            code: arr[i],
            name: name
          }
        } else if (this.dataType === 'name') {
          item = name
        } else {
          item = arr[i]
        }
        res.push(item)
        i++
      }
      return res
    }
  },
  mounted () {
    this.init()
    if (this.canEmit(this.value)) {
      this.setDefaultValue()
    }
  },
  watch: {
    value (val) {
      if (this.canEmit(this.value)) {
        this.setDefaultValue()
      }
    }
  }
}
</script>
